//
//  ZyBaseWebView.swift
//  swift各类控件集锦
//
//  Created by iosdev1 on 2017/5/8.
//  Copyright © 2017年 zyy. All rights reserved.
//

import UIKit
import WebKit

class ZyBaseWebView: WKWebView, WKUIDelegate, WKNavigationDelegate {//, WKScriptMessageHandler
    
    typealias ZyBaseWebViewGetTitleClosure = (String) -> (Void)
    var GetTitleClosure : ZyBaseWebViewGetTitleClosure?
    
    var firstUrl = ""
    
    override init(frame: CGRect, configuration: WKWebViewConfiguration) {
        super.init(frame: frame, configuration: configuration)
        self.initView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func initView() -> Void {
        if #available(iOS 9.0, *) {
            self.allowsLinkPreview = true
        } else {
            // Fallback on earlier versions
        }
        self.allowsBackForwardNavigationGestures = true
        self.initWKWebView()
    }
    
    func initWKWebView() {
        self.navigationDelegate = self as WKNavigationDelegate
        self.uiDelegate = self
    }
    
    //    MARK:   代理WKUIDelegate
    // 创建一个新的WebView
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
           // 接口的作用是打开新窗口委托
        let frameInfo = navigationAction.targetFrame
        if frameInfo?.isMainFrame == false {
            webView.load(navigationAction.request)
        }
        return nil
    }
    
    @available(iOS 9.0, *)
    func webViewDidClose(_ webView: WKWebView) {
        zyUIshowMessage(message: "当web content处理完成时")
    }
    
    /**
     *  web界面中有弹出警告框时调用
     *
     *  @param webView           实现该代理的webview
     *  @param message           警告框中的内容
     *  @param frame             主窗口
     *  @param completionHandler 警告框消失调用
     */
    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        completionHandler()
    }
    
    //HTML页面弹出Confirm时调用此方法
    func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        completionHandler(true)
//        completionHandler([NSString stringWithFormat:@"message:%@\n result:true\nframe:%@",message,frame]);
    }
    
    
    //当用户触摸元素时webView(_:shouldPreviewElement:)立即被调用。返回false将完全禁用该元素的预览，并且阻止其他方法的调用。返回true将提供一个自定义视图控制的机会
    @available(iOS 10.0, *)
    func webView(_ webView: WKWebView, shouldPreviewElement elementInfo: WKPreviewElementInfo) -> Bool {
        return false
    }
    
    
    //如果用户输入Peek，那么webView(_:previewingViewControllerForElement:defaultActions:)为其提供了一个定制视图控制器的机会。返回任何非空视图控制器都会导致视图控制器显示为Peek预览。defaultActions参数是一个活动数组，WebKit Webkit默认使用它作为previewActionItems。如果想要使用这些活动中的任何一个，你只需从视图控制器的previewActionItems执行结果中返回即可,更新后的WKWebView API支持对超链接的预览，为用户呈现自定义视图。通过这个API，你可以通过Peek和Pop手势来触发预览视图，避免跳转去Safari，除此之外，你还可以自定义预览行为
    @available(iOS 10.0, *)
    func webView(_ webView: WKWebView, previewingViewControllerForElement elementInfo: WKPreviewElementInfo, defaultActions previewActions: [WKPreviewActionItem]) -> UIViewController? {
        let controller = UIViewController.init()
        return controller
    }
    
    //如果用户用足够的力触摸来弹出视图控制器，webView(_:commitPreviewingViewController:)将被调用。此时，你可以选择在app中展示弹出的视图控制器。
//    func webView(_ webView: WKWebView, commitPreviewingViewController previewingViewController: UIViewController) {
//        print("用足够的力触摸来弹出视图控制器")
//    }
    
    //    MARK: 代理 WKNavigationDelegate
    // 在发送请求之前，决定是否跳转
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        let URL = navigationAction.request.url
        let url = URL!.absoluteString as NSString
        echo(data: "热乎乎的网址:\(String(describing: url))")
        
//        百度搜索“位置” 获取位置信息
        if url.contains("%E4%BD%8D%E7%BD%AE") {
            zyUIshowMessage(message: "获取位置信息")
        }
        
         //打电话
        if url.hasPrefix("tel:") {
            let phoneNum = url.substring(from: 4)
            let str = "telprompt://" + phoneNum
            UIApplication.shared.openURL(NSURL.init(string: str)! as URL)
            decisionHandler(WKNavigationActionPolicy.cancel)
            return
        }
        
        //    发短信
        if url.hasPrefix("sms:") {
            let phoneNum = url.substring(from: 4)
            let str = "sms://" + phoneNum
            UIApplication.shared.openURL(NSURL.init(string: str)! as URL)
            decisionHandler(WKNavigationActionPolicy.cancel)
            return
        }
        
        decisionHandler(WKNavigationActionPolicy.allow)
        return
    }

//     在收到响应后，决定是否跳转
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        echo(data: "在收到响应后，决定是否跳转")
        decisionHandler(WKNavigationResponsePolicy.allow)
        return
    }
    
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        echo(data: "页面开始加载时调用")
    }
    
    func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
        echo(data: "接收到服务器跳转请求之后调用")
    }
    
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        echo(data: "页面加载失败")
    }
    
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        echo(data: "当内容开始返回时调用")
    }
    
    // 页面加载完成之后调用
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        if (self.GetTitleClosure != nil) {
            self.GetTitleClosure!(webView.title!)
        }
        
         //获取页面高度，并重置webview的frame
        self.evaluateJavaScript("document.body.offsetHeight") { (result, error) in
            if (error == nil) {
                let height = result as! CGFloat
                UIView.animate(withDuration: 2, animations: {                   
                    webView.frame = CGRect(x:10, y:10, width:WIDTH_SCREEN-20.0, height:height - 20.0)
                })
            }
        }
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        echo(data: "下载数据失败")
    }
    
    // 这与用于授权验证的API，与AFN、UIWebView的授权验证API是一样的
    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            if challenge.previousFailureCount == 0 {
                let credential = URLCredential.init(trust: challenge.protectionSpace.serverTrust!)
                completionHandler(URLSession.AuthChallengeDisposition.useCredential, credential)
            }else {
            completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
            }
        }else {
        completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
        }
    }
    
    // 当web content处理完成时，会回调
    func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
        
    }
    
    
    //    MARK: 代理 WKScriptMessageHandler
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        
    }
    
    /*!
     @method
     @brief 加载Url
     @discussion
     @param url
     */
    func YgLoadUrl(url:String) {
//        拼接各种参数
        let request = NSURLRequest.init(url: NSURL.init(string: url)! as URL)
        self.load(request as URLRequest)
        firstUrl = (request.url?.absoluteString)!
    }
    
    /*!
     @method 读取本地HTML
     @brief 加载Url
     @discussion
     @param url
     */
    func YgLoadLocationUrl(url:String) -> Void {
        let path = Bundle.main.path(forResource: url, ofType: "html")
        if ((path) != nil) {
            let fileUrl = NSURL.fileURL(withPath: path!)
            if #available(iOS 9.0, *) {
                self.loadFileURL(fileUrl, allowingReadAccessTo: fileUrl)
            } else {
                self.load(NSURLRequest.init(url: fileUrl) as URLRequest)
            }
        }
    }
    
    /*!
     @method 读取无参数HTML
     @brief 加载Url
     @discussion
     @param url
     */
    func YgLoadNoneParaUrl(url:String) -> Void {
        let request = NSURLRequest.init(url: NSURL.init(string: url)! as URL)
        self.load(request as URLRequest)
        firstUrl = (request.url?.absoluteString)!
    }
}
